// codegen.c
#include "Yecc.h"
#include <stdarg.h>

FILE *AsmOut = NULL;

void emit(const char *fmt, ...) {
    va_list args;
    va_start(args, fmt);
    vprintf(fmt, args);
    assert(AsmOut != NULL);
    vfprintf(AsmOut, fmt, args);
    va_end(args);
    return ;
}

void GenStmt(struct Node* node);

void Codegen(struct Node* root) {

    AsmOut = fopen("./build/code.asm", "w");

    emit(".section entry, \"ax\"\n");
    emit(".globl _start\n");
    emit("_start:\n");
    emit("    li sp, 0xF0000000\n");
    GenStmt(root);
    emit("_halt:\n");
    emit("    j _halt\n");
    return ;
}

void GenStmt(struct Node* node) {

    switch (node->kind) {
        case ND_NUM:
            emit("    li a0, %ld\n", node->num);
            return;
        case ND_ADD:
            GenStmt(node->left);
            emit("    addi sp, sp, -8\n");
            emit("    sd a0, 0(sp)\n");
            GenStmt(node->right);
            emit("    ld t0, 0(sp)\n");
            emit("    addi sp, sp, 8\n");
            emit("    add a0, t0, a0\n");
            return;
        default:
            emit("Error: unsupported kind %d\n", node->kind);
            assert(0);
    }
}
